import { useEffect } from 'react'
import { useSetState } from 'ahooks'
import draggable from '../draggable'

const useSlider = (type, vertical, { color, onChange }, { $el, bar, thumb }) => {
  const caclute = type === 'alpha' ? 100 : 360

  const [state, setState] = useSetState({
    thumbLeft: 0,
    thumbTop: 0,
    background: null
  })

  useEffect(() => {
    const dragConfig = {
      drag: (event) => handleDrag(event),
      end: (event) => handleDrag(event)
    }
    draggable(bar.current, dragConfig)
    draggable(thumb.current, dragConfig)
    update()
  }, [])

  useEffect(() => {
    update()
  }, [color.value])

  const handleClick = (event) => {
    const target = event.target
    if (target !== thumb.current) {
      handleDrag(event)
    }
  }

  const handleDrag = (event) => {
    const rect = $el.current.getBoundingClientRect()
    let dragVal
    if (!vertical) {
      let left = event.clientX - rect.left
      left = Math.max(thumb.current.offsetWidth / 2, left)
      left = Math.min(left, rect.width - thumb.current.offsetWidth / 2)
      dragVal = Math.round(
        ((left - thumb.current.offsetWidth / 2) / (rect.width - thumb.current.offsetWidth)) *
          caclute
      )
    } else {
      let top = event.clientY - rect.top
      top = Math.min(top, rect.height - thumb.current.offsetHeight / 2)
      top = Math.max(thumb.current.offsetHeight / 2, top)
      dragVal = Math.round(
        ((top - thumb.current.offsetHeight / 2) / (rect.height - thumb.current.offsetHeight)) *
          caclute
      )
    }
    color.set(type, dragVal)
    onChange(color)
  }

  const getThumbLeft = () => {
    if (vertical) return 0
    const el = $el.current
    if (!el) return 0
    return Math.round(
      (color.get(type) * (el.offsetWidth - thumb.current.offsetWidth / 2)) / caclute
    )
  }

  const getThumbTop = () => {
    if (!vertical) return 0
    const el = $el.current
    if (!el) return 0
    return Math.round(
      (color.get(type) * (el.offsetHeight - thumb.current.offsetHeight / 2)) / caclute
    )
  }

  const getBackground = () => {
    if (color && color.value) {
      const { r, g, b } = color.toRgb()
      return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, 0) 0%, rgba(${r}, ${g}, ${b}, 1) 100%)`
    }
    return null
  }

  const update = () => {
    setState({
      thumbLeft: getThumbLeft(),
      thumbTop: getThumbTop(),
      background: type === 'alpha' && getBackground()
    })
  }

  return [state, handleClick]
}

export default useSlider
